package com.jrx.anytxn.investor.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.customer.dto.customer.CustomerFirstLevelRes;
import com.jrx.anytxn.customer.dto.customer.CustomerRes;
import com.jrx.anytxn.customer.dto.customer.CustomerSecondLevelRes;
import com.jrx.anytxn.investor.constant.TransBizConstant;
import com.jrx.anytxn.investor.entity.*;
import com.jrx.anytxn.investor.service.IInvestorLoanService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.dto.system.SystemParameterRes;
import com.jrx.anytxn.param.entity.PrInvestorTable;
import com.jrx.anytxn.param.service.investor.IPrInvestorTableService;
import com.jrx.anytxn.param.service.system.ISystemParameterService;
import com.jrx.anytxn.ribbon.config.GrayVersionConfig;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.param.service.system.ISequenceNumberService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 客户出资方放款审批Service接口实现
 *
 * @author liuyang
 * @date 2020-06-16
 */
@Service
public class InvestorLoanServiceImpl implements IInvestorLoanService {

    private static final Logger logger = LoggerFactory.getLogger(InvestorLoanServiceImpl.class);

    @Autowired
    private ISegmentService segmentService;

    @Autowired
    private ISystemParameterService systemParameterService;

    @Autowired
    private IPrInvestorTableService investorTableService;

    @Autowired
    private GrayVersionConfig grayVersionConfig;
    @Autowired
    ISequenceNumberService sequenceNumberService;
    /**
     * 构建资金限制流水
     *
     * @param investorTable 出资方信息
     * @param fundRouteLog  资金源路由记录
     * @param amount        交易金额
     * @param fundId        资金源id
     * @param restraintType 限制类型
     * @param businessDate  业务日期
     * @param restraintNo   限制编号
     * @return TlFundRestraintLog 资金限制流水
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-06-16
     */
    @Override
    public TlFundRestraintLog buildTlFundRestraintLog(PrInvestorTable investorTable, TlFundRouteLog fundRouteLog, BigDecimal amount, String fundId, String restraintType, Date businessDate, String restraintNo) throws TxnBizException {
        TlFundRestraintLog log = new TlFundRestraintLog();
        try {
            log.setId(segmentService.getId(TransBizConstant.TL_FUND_RESTRAINT_LOG));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        log.setTenantId(investorTable.getTenantId());// 租户ID
        log.setOrganizationId(investorTable.getOrganizationId());// 机构号
        log.setAmount(amount);// 交易金额
        log.setFundId(fundId);// 资金源ID
        log.setInvestorId(investorTable.getInvestorId());// 出资方ID
        log.setLoanSeqNo(fundRouteLog.getSeqNo());// 贷款流水号
        log.setCustomerId(fundRouteLog.getCustomerId());// 客户号
        log.setSeqNo(sequenceNumberService.generateRefNo(Constant.SEQUENCE_LENGTH));// 交易流水号
        log.setAcctNo(investorTable.getPrepaidAccount());// 账号
        log.setRestraintNo(restraintNo); // 限制编号
        log.setRestraintType(restraintType);// 限制类型
        log.setRestraintStatus("");// 限制状态
        log.setBusinessDate(businessDate);// 业务日期
        log.setUpdateBy(TransBizConstant.SYS_OPRATE);// 最后更新操作员
        log.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);// 记录版本号
        return log;
    }

    /**
     * 构建限制流水
     *
     * @param fundRestraintLog 原限制流水
     * @param restraintType    限制类型
     * @param restraintNo      限制编号
     * @return
     * @throws TxnBizException
     */
    @Override
    public TlFundRestraintLog buildTlFundRestraintLog(TlFundRestraintLog fundRestraintLog, String restraintType, String restraintNo) throws TxnBizException {
        TlFundRestraintLog log = new TlFundRestraintLog();
        BeanMapping.copy(fundRestraintLog, log);
        try {
            log.setId(segmentService.getId(TransBizConstant.TL_FUND_RESTRAINT_LOG));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        log.setRestraintType(restraintType);
        log.setSeqNo(sequenceNumberService.generateRefNo(Constant.SEQUENCE_LENGTH));
        log.setRestraintNo(restraintNo);
        log.setCreateTime(null);
        log.setUpdateTime(null);
        log.setUpdateBy(TransBizConstant.SYS_OPRATE);
        log.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        return log;
    }

    /**
     * 构建放款出资方审批记录
     *
     * @param fundRouteLog  资金源路由记录
     * @param customerRes   客户信息
     * @param investorId    出资方id
     * @param loanAmount    借款金额
     * @param fundId        资金源id
     * @param routeOrder    路由顺序
     * @param resultMessage 结果信息
     * @return TlInvestorLoanApproveLog 放款出资方审批记录
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-06-16
     */
    @Override
    public TlInvestorLoanApproveLog buildTlInvestorLoanApproveLog(TlFundRouteLog fundRouteLog, CustomerRes customerRes, String investorId, BigDecimal loanAmount, String fundId, Integer routeOrder, String resultMessage) throws TxnBizException {

        CustomerFirstLevelRes firstLevel = customerRes.getFirstLevel();
        CustomerSecondLevelRes secondLevel = customerRes.getSecondLevel();

        TlInvestorLoanApproveLog log = new TlInvestorLoanApproveLog();
        BeanMapping.copy(fundRouteLog, log);
        try {
            log.setId(segmentService.getId(TransBizConstant.TL_INVESTOR_LOAN_APPROVE_LOG));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        log.setInvestorId(investorId);// 出资方id
        log.setIdNumber(firstLevel.getIdNumber());// 证件号
        log.setMobile(secondLevel.getMobile());// 手机号
        log.setLoanAmount(loanAmount);// 借款金额
        log.setCreateTime(null);// 创建时间
        log.setUpdateTime(null);// 最后更新时间
        log.setUpdateBy(TransBizConstant.SYS_OPRATE);// 最后更新操作员
        log.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);// 记录版本号
        log.setFundId(fundId); // 资金源id
        log.setRouteOrder(routeOrder); // 路由顺序
        log.setResultMessage(resultMessage); // 结果信息
        return log;
    }

    /**
     * 构建资金转账流水
     *
     * @param loanMainInfo 对客订单
     * @param seqNo        交易流水号
     * @param businessDate 业务日期
     * @param transferType 转账类型
     * @return TlFundTransferLog 资金转账流水
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-06-16
     */
    @Override
    public TlFundTransferLog buildTlFundTransferLog(AmLoanMainInfo loanMainInfo, String seqNo, Date businessDate, String transferType) throws TxnBizException {

        TlFundTransferLog log = new TlFundTransferLog();
        BeanMapping.copy(loanMainInfo, log);
        try {
            log.setId(segmentService.getId(TransBizConstant.TL_FUND_TRANSFER_LOG));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        log.setAmount(loanMainInfo.getLoanAmount());// 交易金额
        log.setSeqNo(seqNo);// 交易流水号
        log.setBusinessDate(businessDate);// 业务日期
        log.setTransferType(transferType);// 转账类型
        log.setNarrative("放款");// 交易描述
        log.setRefNo(sequenceNumberService.generateRefNo(Constant.SEQUENCE_LENGTH));// 交易参考号
        log.setCreateTime(null);// 创建时间
        log.setUpdateTime(null);// 最后更新时间
        log.setUpdateBy(TransBizConstant.SYS_OPRATE);// 最后更新操作员
        log.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);// 记录版本号
        log.setGrayVersion(grayVersionConfig.getCurrentVersion());
        return log;
    }

    /**
     * 构建资金转账明细
     *
     * @param fundRestraintLogs 资金源限制流水
     * @param fundTransferLog   转账记录
     * @param currency          币种
     * @param investorIds       出资方id
     * @param bankLoanAmount    本行借款金额
     * @return TlFundTransferDetail 资金转账明细
     * @throws TxnBizException
     */
    @Override
    public List<TlFundTransferDetail> buildTlFundTransferDetails(List<TlFundRestraintLog> fundRestraintLogs, TlFundTransferLog fundTransferLog, String currency, Set<String> investorIds, BigDecimal bankLoanAmount) throws TxnException {

        List<TlFundTransferDetail> fundTransferDetails = new ArrayList<>();
        BigDecimal amount = BigDecimal.ZERO; // 计算贷方的交易金额

        // 构建借方的资金转账明细
        for (String investorId : investorIds) {

            TlFundTransferDetail detail = new TlFundTransferDetail();
            BeanMapping.copy(fundTransferLog, detail);
            try {
                detail.setId(segmentService.getId(TransBizConstant.TL_FUND_TRANSFER_DETAIL));// 主键
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }
            detail.setTransferSeqNo(fundTransferLog.getSeqNo());// 交易流水号
            detail.setInvestorId(investorId);// 出资方id
            detail.setCrDrInd(TransBizConstant.CR_DR_IND_D);// 借方
            detail.setNarrative("放款借记");// 交易描述
            detail.setCurrency(currency);// 币种
            detail.setCreateTime(null);// 创建时间

            // 本行的转账记录
            if (TransBizConstant.BANK_INVESTOR_ID.equals(investorId)) {
                // 获取本行出资方信息
                PrInvestorTable investorTable = investorTableService.findInvestorByInvestorId(investorId, fundTransferLog.getTenantId());
                detail.setAcctNo(investorTable.getPrepaidAccount()); // 账号
                detail.setAmount(bankLoanAmount);// 交易金额
                detail.setRestraintSeqNo("");// 限制流水
                detail.setRestraintType("");//限制类型
            } else {
                // 获取对应的限制流水
                TlFundRestraintLog fundRestraintLog = fundRestraintLogs.stream().filter(log -> log.getInvestorId().equals(investorId)).findFirst().get();
                detail.setAcctNo(fundRestraintLog.getAcctNo()); // 账号
                detail.setAmount(fundRestraintLog.getAmount()); // 交易金额
                detail.setRestraintSeqNo(fundRestraintLog.getSeqNo());// 限制流水
                detail.setRestraintType(fundRestraintLog.getRestraintType());//限制类型
            }

            fundTransferDetails.add(detail);
            amount = amount.add(detail.getAmount());
        }

        // 构建贷方的资金转账明细
        SystemParameterRes systemParameter = systemParameterService.findByParamCode(TransBizConstant.THIRD_ACCT_NO, fundRestraintLogs.get(0).getTenantId());
        TlFundTransferDetail detail = new TlFundTransferDetail();
        BeanMapping.copy(fundRestraintLogs.get(0), detail);
        try {
            detail.setId(segmentService.getId(TransBizConstant.TL_FUND_TRANSFER_DETAIL));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        detail.setInvestorId("");// 中间账户没有出资方id
        detail.setTransferSeqNo(fundTransferLog.getSeqNo());// 交易流水号
        detail.setCrDrInd(TransBizConstant.CR_DR_IND_C);// 贷方
        detail.setNarrative("放款贷记");// 交易描述
        detail.setCurrency(currency);// 币种
        detail.setCreateTime(null);// 创建时间
        detail.setAcctNo(systemParameter.getParamValue());// 账号
        detail.setAmount(amount);// 交易金额
        fundTransferDetails.add(detail);

        return fundTransferDetails;
    }

    /**
     * 构建资金转账流水
     *
     * @param origFundTransferLog 原资金转账流水
     * @param businessDate        业务日期
     * @param transferType        转账类型
     * @return TlFundTransferLog 资金转账流水
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-06-17
     */
    @Override
    public TlFundTransferLog buildTlFundTransferLog(TlFundTransferLog origFundTransferLog, Date businessDate, String transferType) throws TxnBizException {
        TlFundTransferLog log = new TlFundTransferLog();
        BeanMapping.copy(origFundTransferLog, log);
        try {
            log.setId(segmentService.getId(TransBizConstant.TL_FUND_TRANSFER_LOG));// 主键
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        log.setBusinessDate(businessDate);// 业务日期
        log.setTransferType(transferType);// 转账类型
        log.setNarrative("放款");// 交易描述
        log.setRefNo(sequenceNumberService.generateRefNo(Constant.SEQUENCE_LENGTH));// 交易参考号
        log.setOrignRefNo(origFundTransferLog.getRefNo());// 源交易参考号
        log.setCreateTime(null);// 创建时间
        log.setUpdateTime(null);// 最后更新时间
        log.setUpdateBy(TransBizConstant.SYS_OPRATE);// 最后更新操作员
        log.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);// 记录版本号
        log.setGrayVersion(grayVersionConfig.getCurrentVersion());
        return log;
    }
}
